package com.wandian.texas;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.PropertyConfigurator;

import com.wandian.executor.TimerCommand;
import com.wandian.executor.TimerMgr;
import com.wandian.texas.db.CommonDaoManager;
import com.wandian.texas.db.DBMgr;
import com.wandian.texas.db.Result;
import com.wandian.texas.entity.CornucopiaEntity;
import com.wandian.texas.protocol.Protocol;
import com.wandian.util.Config;
import com.wandian.util.ConsoleTable;
import com.wandian.util.DateUtil;
import com.wandian.util.Log;
import com.wandian.util.PathUtil;
import com.wandian.util.TimeWatch;
import com.wandian.xml.RoomConfigItem;
import com.wandian.texas.demo.Test;

/**
 * @author long
 * @Create 2012-10-15 下午3:40:51
 * @QQ 108232706
 * @version 1.0
 * @description GameServer
 */
public class GameServer {
	private static ThreadRun callBackThread = null;
	private static List<String> consoleCommands = new ArrayList<String>();
	public static CenterRequestor requestor;

	public static void main(String[] args) {
		GameData.CONFIGPATH = PathUtil.getAasolutePath(args[0]);// String.format("%s/%s",
		if (!Config.initConfig(GameData.CONFIGPATH)) {
			System.out.println("系统配置文件加载错误，程序退出!");
			return;
		} else {
			PropertyConfigurator.configure(PathUtil.getAasolutePath(Config.getValue("log4j.path")));
			Log.debug("加载配置文件成功");
		}

		Log.info(String.format("[GameServer][%s]游戏服务器准备启动", DateUtil.format(new Date())));
		GameData.MAINSTARTTIME = System.currentTimeMillis();
		try {
			// PropertyConfigurator.configure(Config.getValue("log4j.path"));
			if (args.length <= 0) {
				Log.error(String.format("[GameServer][%s]游戏服务器准备启动错误,请输入配置文件地址路径...", DateUtil.format(new Date())));
				return;
			}
			consoleCommands.add("startup");
			consoleCommands.add("shutdown");
			consoleCommands.add("cmdthread");
			consoleCommands.add("current");
			consoleCommands.add("testthreadpool");
			consoleCommands.add("shuttestthreadpool");
			consoleCommands.add("starttimer");
			consoleCommands.add("stoptimer");
			consoleCommands.add("exit");
			CommonDaoManager.init(1);// 启动通用数据库
			if (!GameData.initDbConfig()) {
				Log.error("初始化系统全局的配置错误，程序退出!");
				return;
			}
			GameData.SERVER = CommonDaoManager.ServerListDao(0).find(Config.getInt("server.id"));
			if (GameData.SERVER == null) {
				throw new Exception("寻找服务器端口等配置信息失败!");
			}
			if (GameData.SERVER.ServerIndex < 0) {
				throw new Exception("服务器ServerIndex应该大于0!");
			}
			// 从GameDb加载信息
			if (!CommonDaoManager.GameRoomDao(0).getServerInfo()) {
				throw new Exception("服务器加载ServerDB错误,请确定ServerIndex!");
			}
			GameData.SERVER.GameId = GameData.getInt("GAMEID");
			// 启动,清除accountDB里LoginOnly
			if (!CommonDaoManager.GameRoomDao(0).clearOnlyLogin()) {
				throw new Exception("启动,清除accountDB里LoginOnly,请检查存储过程[AccountDB]GameServerClearOnly!");
			}
			GameData.checkLoginOnly = Config.getInt("game.checkloginonly") == 1 ? true : false;
			Log.info(String.format("[GameServer]本服务器信息:%s", GameData.SERVER));
			CommonDaoManager.UserInfoDao(0).exeSql("  UPDATE PlayerInfo SET  CurrentState=0 WHERE ServerId=? ;", DBMgr.TexasPokerDB, GameData.SERVER.ServerId);
			if (!RoomMgr.init())
				return;
			requestor = new CenterRequestor("CenterRequestor" + GameData.SERVER.ServerId, GameData.getString("CenterServerIp"), GameData.getInt("CenterServerPort"));
			if (!requestor.connect()) {
				Log.error("连接中心服务器错误，程序退出!");
				return;// 继续游戏，只是通知一下，不影响游戏，
			} else {
				requestor.requestLogin();
				requestor.start();
			}
			Log.info("连接中心服务中.....请稍后....");
			if (!requestor.isValid) {
				synchronized (requestor.syn) {
					requestor.syn.wait();
				}
			}
			try {
				if (!requestor.connected || !requestor.isValid) {
					Log.info("连接中心服务失败，程序退出");
					return;
				} else {
					Log.info("连接中心服务成功");
				}
			} catch (Exception e) {
			} finally {
			}
			if (startUpSessionMgr())
				startSessionMgr();
			// 启动,清除accountDB里LoginOnly
			if (!CommonDaoManager.GameRoomDao(0).clearOnlyLogin()) {
				Log.error("启动,清除accountDB里LoginOnly,请检查存储过程[AccountDB]GameServerClearOnly!");
				return;
			}
//			CommonDaoManager.close();
		} catch (IOException e) {
			e.printStackTrace();
			Log.info(String.format("[GameServer]运行异常:%s", e));
		} catch (Throwable e) {
			e.printStackTrace();
			Log.info(String.format("[GameServer]运行异常:%s", e));
		}
		if (requestor != null)
			requestor.isService = false;

		GameData.MAINSTOPTIME = System.currentTimeMillis();
		Log.info(String.format("[GameServer][%s]游戏服务器已退出,总计运行时间:%s", DateUtil.format(new Date()), TimeWatch.getTime(GameData.MAINSTOPTIME - GameData.MAINSTARTTIME)));
	}

	public static boolean initComponent(boolean initResult, String componentName) {
		if (!initResult)
			Log.error(componentName + "错误");
		else {
			Log.info(componentName + "加载完成");
		}
		return initResult;
	}

	public static void startSessionMgr() throws IOException {
		String mycmd;
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			while (true) {
				mycmd = br.readLine();
				try {

					// if (!consoleCommands.contains(mycmd)) {
					// TimeUnit.MILLISECONDS.sleep(1);
					// Log.info(String.format(
					// "[GameServer][%s] 命令不支持!详细命令参考:%s",
					// DateUtil.format(new Date()),
					// consoleCommands.toString()));
					// continue;
					// }
					if ("exit".equals(mycmd)) {
						shutDownSessionMgr();
						SessionMgrImp.getInstance().exitThread();
						requestor.isService = false;
						break;
					} else if ("startup".equals(mycmd)) {
						startUpSessionMgr();
					} else if ("shutdown".equals(mycmd)) {
						pauseSessionMgr();
					} else if ("testthreadpool".equals(mycmd)) {
						testThreadPool();
					} else if ("shuttestthreadpool".equals(mycmd)) {
						TimerMgr.shutdownNow();
					} else if ("cmdthread".equals(mycmd)) {
						printThreadPoolStatus();
					} else if ("current".equals(mycmd)) {
						printThreadPoolCurrentStatus();
					} else if ("starttimer".equals(mycmd)) {
						testStartTimer(15L);
					} else if ("stoptimer".equals(mycmd)) {
						testStopTimer();
					} else if (mycmd.startsWith("status")) {
						try {
							short status = Short.valueOf(mycmd.substring(6));
							callBackThread.status = status;
						} catch (Exception e) {
							e.printStackTrace();
						} finally {
						}
					} else if (mycmd.startsWith("robot")) {
						try {
							TestGamePool.GameId = Integer.valueOf(mycmd.substring(5));
							System.out.println(TestGamePool.GameId);
							Test.testRobot();
						} catch (Exception e) {
							e.printStackTrace();
						} finally {
							Test.outRobot();
						}
					} else if ("rooms".equals(mycmd)) {
						int roomcout = RoomMgr.roomsList.size();
						RoomConfigItem room;
						StringBuilder sb = new StringBuilder();
						ArrayList<SessionObject> roomUsers;
						for (int i = 0; i < roomcout; i++) {
							room = RoomMgr.roomsList.get(i);
							roomUsers = room.roomUsers();
							if (roomUsers.size() < 1)
								continue;
							sb.append("room:" + room.id + " code " + room.roomCode + "[状态]" + room.isPlaying() + " gameid:" + room.gameId() + " step:" + room.step() + " AccepStep" + room.gameRoom.AccepStep + " curSeatId:" + room.curSeatId() + " 用户数:" + roomUsers.size() + " 坐位用户:" + room.roomSeatSize() + " ");
							for (SessionObject s : roomUsers) {
								sb.append(s.getUser() + "|");
							}
							sb.append("\r\n");
						}
						sb.append(" 房间数:" + roomcout + "以下是在线用户:" + UserMgr.I().onlineUserList.size());
						for (SessionObject s : UserMgr.I().onlineUserList) {
							sb.append(s.getUser() + "\r\n");
						}
						Log.info(sb.toString());
					} else if (mycmd.startsWith("seeroom")) {
						try {
							int roomid = Integer.valueOf(mycmd.substring(7));
							RoomConfigItem room = RoomMgr.getRoom(roomid);
							Log.info(room == null ? "null" : room.getInfo());
						} catch (Exception e) {
						}
					} else if (mycmd.startsWith("seeuser")) {
						try {
							int userid = Integer.valueOf(mycmd.substring(7));
							SessionObject session = UserMgr.I().onlineUserMap.get(userid);
							Log.info(session == null ? "null" : session.getInfo());
						} catch (Exception e) {
						}
					} else if ("testInsertCornucopia".equals(mycmd)) {
						testInsertCornucopia();
					} else if ("testGetPagination".equals(mycmd)) {
						testGetPagination();
					} else {
						Log.info("[GameServer] 命令不支持!");
					}
				} catch (Exception e) {
					Log.info("[GameServer]运行异常%s!", e);
					// break;
				}
				TimeUnit.MILLISECONDS.sleep(1);
			}// end while
			br.close();
		} catch (InterruptedException e) {
			Log.info(String.format("[GameServer][%s] 运行中出现异常:%s!", DateUtil.format(new Date()), e));
		}
		requestor.isService = false;
	}

	public static void testGetPagination() {
		// CommonDaoManager.GameRoomDao(0).getPagination("t_Cornucopia", null,
		// null, 1, 11, "  Order By WinTime desc ", null);
		Result rs = new Result() {
			@Override
			public void run() {
				try {
					if (!this.IsSuccess || this.RowSize < 1)
						return;
					this.DataRows = new Object[this.RowSize][2];
					int index = 0;
					while (this.ResultSet.next()) {
						this.DataRows[index][0] = this.ResultSet.getString(1);
						this.DataRows[index][1] = this.ResultSet.getString(2);
						index++;
					}
					System.out.println(this);

				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		};
		CommonDaoManager.GameRoomDao(0).getPagination(rs, "t_ServerList", " where ServerId=1 ", " ServerIp,ServerKey ", 1, 11, "", "ServerId");
		if (rs.IsSuccess) {
			Log.debug(rs.getRows());
		}
	}

	private static void testInsertCornucopia() {
		ArrayList<CornucopiaEntity> Cornucopias = new ArrayList<CornucopiaEntity>();
		for (int i = 0; i < 1; i++) {
			CornucopiaEntity cornucopia = new CornucopiaEntity(1, 1, i, 4, "诸葛亮", 9, "AsKsQsJsTs");
			cornucopia.WinMoney = 10000;
			Cornucopias.add(cornucopia);
		}
		CommonDaoManager.GameRoomDao(0).addCornucopiasBySp(Cornucopias);
	}

	private static void testStopTimer() {
		Log.debug("剩余时间ms:" + timer.getLeftTime(TimeUnit.MILLISECONDS));
		// if (ThreadPool.getInstance().cancel(timer)) {
		// System.out.println("移除任务成功1");
		// } else {
		// System.out.println("移除任务失败1");
		// }
	}

	static TimerCommand timer;

	private static void testStartTimer(Long delay) {
		// timer.put("SocketCmd", cmdObject);
		cur_port();
		// cur_port();
		// show();
		// ports();
		// gameover();
	}

	public static void cur_port() {
		System.out.println("第1边池形成");
		timer = new TimerCommand("DelayMessageCmd", Protocol.CHATROOM_DELAY_MESSAGE, 1, TimeUnit.SECONDS);
		timer.put("Type", 11);
		Log.debug("1秒后,show");
		ThreadPool.getInstance().Push(timer);
	}

	public static void show() {
		System.out.println("诸葛亮 牌型为一对,诸葛亮 牌型为一对  ");
		timer.put("Type", 12);
		timer.delay(2000, TimeUnit.MILLISECONDS);
		Log.debug("2秒后");
		ThreadPool.getInstance().Push(timer);
	}

	public static void ports() {
		System.out.println("##赢得主池1000");
		timer.put("Type", 13);
		timer.delay(3500, TimeUnit.MILLISECONDS);
		Log.debug("3.5秒后");
		ThreadPool.getInstance().Push(timer);
	}

	public static void gameover() {
		System.out.println("游戏结束 ");
	}

	private static void printThreadPoolStatus() {
		ThreadPool.getInstance().printThreadPoolStatus();
	}

	private static boolean startUpSessionMgr() {
		if (SessionMgrImp.getInstance().isStarted()) {
			Log.info(String.format("[GameServer]SessionMgr已启动!"));
			return false;
		} else {
			try {
				if (SessionMgrImp.getInstance().start()) {// Config.getInt("server.port"),
															// Config.getInt("server.sessionMaxCount"),
															// Config.getInt("server.cmdThreadCount"),
															// Config.getInt("server.cmdQueueCount")))
															// {
					if (callBackThread == null) {
						callBackThread = new ThreadRun(SessionMgrImp.getInstance());
						callBackThread.setRun(true);
						callBackThread.start();
					}
					Log.info(String.format("[GameServer][%s] SessionMgr启动成功!", DateUtil.format(new Date())));
					GameMgr.startAllTimer();
					callBackThread.status = 0;
					return true;
				} else {
					SessionMgrImp.getInstance().stop(true);
					Log.info(String.format("[GameServer][%s] SessionMgr启动失败!", DateUtil.format(new Date())));
				}
			} catch (Throwable e) {
				e.printStackTrace();
				Log.info(String.format("[GameServer][%s] SessionMgr启动异常:%s!", DateUtil.format(new Date()), e));
			}
		}
		return false;
	}

	private static void shutDownSessionMgr() {
		// 正常命令
		GameMgr.stopAllTimer();
		if (!SessionMgrImp.getInstance().isStarted()) {
			Log.info(String.format("[GameServer][%s] SessionMgr未启动!", DateUtil.format(new Date())));
		} else {
			if (SessionMgrImp.getInstance().isStarted()) {
				SessionMgrImp.getInstance().stop(true);
				Log.info(String.format("[GameServer][%s]游戏服务器SessionMgr已停止", DateUtil.format(new Date())));
			}
		}
		callBackThread.setRun(false);
	}

	private static void pauseSessionMgr() {
		// 正常命令
		if (callBackThread == null)
			return;
		callBackThread.status = 1;
		if (!SessionMgrImp.getInstance().isStarted()) {
			Log.info(String.format("[GameServer][%s] SessionMgr未启动!", DateUtil.format(new Date())));
		} else {
			if (SessionMgrImp.getInstance().isStarted()) {
				SessionMgrImp.getInstance().stop(false);
				Log.info(String.format("[GameServer][%s]游戏服务器SessionMgr已暂停", DateUtil.format(new Date())));
			}
		}
	}

	public static void printThreadPoolCurrentStatus() {
		System.out.println("==============Main Thread Current Status=============");
		ConsoleTable t = new ConsoleTable(5, true);
		t.appendRow();
		t.appendColum("序号").appendColum("线程id").appendColum("isInterrupted").appendColum("isAlive").appendColum("isDaemon");
		t.appendRow();
		t.appendColum(1).appendColum(callBackThread.getName()).appendColum(callBackThread.isInterrupted()).appendColum(callBackThread.isAlive()).appendColum(callBackThread.isDaemon());
		t.appendRow();
		t.appendColum(2).appendColum(Thread.currentThread().getName()).appendColum(Thread.currentThread().isInterrupted()).appendColum(Thread.currentThread().isAlive()).appendColum(Thread.currentThread().isDaemon());
		t.appendColum(3).appendColum(callBackThread.getName()).appendColum(callBackThread.isInterrupted()).appendColum(callBackThread.isAlive()).appendColum(callBackThread.isDaemon());
		Log.info(t.toString());
		SessionMgrImp.getInstance().printThreadPoolCurrentStatus();
		ThreadPool.getInstance().printThreadPoolCurrentStatus();
	}

	private static void testThreadPool() {
		ThreadPool.getInstance().Push(new TimerCommand("1", 2000L, 2000L, 5));
		ThreadPool.getInstance().Push(new TimerCommand("2", 4000L, 4000L, 5));
		// ThreadPool.getInstance().Push(new TimerCommand("3", 2000L, 1000L,
		// 2));
		// ThreadPool.getInstance().Push(new TimerCommand("4", 3000L, 1000L,
		// 3));
		// ThreadPool.getInstance().Push(new TimerCommand("5", 100L, 1100L, 5));
		// ThreadPool.getInstance().Push(new TimerCommand("6", 200L, 1200L, 5));
		// ThreadPool.getInstance().Push(new TimerCommand("7", 300L, 1300L, 5));
		// if (TimerMgr.init(10)) {
		// for (int i = 0; i < 10; i++) {
		// TimerMgr.push(new Runnable() {
		// public void run() {
		// ThreadPool.getInstance().Push(new TimerCommand("1", 1000L, 1000L,
		// 2));
		// ThreadPool.getInstance().Push(new TimerCommand("2", 4000L, 1000L,
		// 1));
		// ThreadPool.getInstance().Push(new TimerCommand("3", 2000L, 1000L,
		// 2));
		// ThreadPool.getInstance().Push(new TimerCommand("4", 3000L, 1000L,
		// 3));
		// ThreadPool.getInstance().Push(new TimerCommand("5", 100L, 1100L, 5));
		// ThreadPool.getInstance().Push(new TimerCommand("6", 200L, 1200L, 5));
		// ThreadPool.getInstance().Push(new TimerCommand("7", 300L, 1300L, 5));
		// }
		// }, 1, 1);
		// }
		// }
		// // 10分钟之后停止
		// TimerMgr.shutdown(1, TimeUnit.MINUTES);
	}
}
